package com.security.securityandoauth.config;

import com.security.securityandoauth.handler.*;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.core.userdetails.User;
import org.springframework.security.core.userdetails.UserDetailsPasswordService;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.provisioning.InMemoryUserDetailsManager;
import org.springframework.security.web.SecurityFilterChain;

import static org.springframework.security.config.Customizer.withDefaults;

/*
    基于内存的用户认证
 */

@Configuration
public class WebSecurityConfig {

    // 基于内存的用户认证
//    @Bean
//    public UserDetailsService userDetailsService() {
//        // 创建基于内存的用户详情管理器
//        InMemoryUserDetailsManager userDetailsManager = new InMemoryUserDetailsManager();
//        // 使用该管理器创建 UserDetails 对象
//        userDetailsManager.createUser(
//                // 硬编码的方式创建用户
//                User.withDefaultPasswordEncoder()
//                        .username("user")
//                        .password("123")
//                        .roles("users")
//                        .build()
//        );
//        // 返回该管理器
//        return userDetailsManager;
//    }

    // 过滤器链设置
    @Bean
    public SecurityFilterChain securityFilterChain(HttpSecurity httpSecurity) throws Exception {
        return httpSecurity
                // 对所有请求开启请求保护
                .authorizeHttpRequests(authorize -> authorize
                        // 无需授权即可访问
//                        .requestMatchers("/test").permitAll()
                        // 用户-权限-资源
                        // 需要对于角色才可访问
//                        .requestMatchers("/test").hasRole("admin")
                        // 需要对于权限才可访问
                        .requestMatchers("/test").hasAnyAuthority("users")
                        // 任意请求都需要认证
                        .anyRequest().authenticated()
                )

                // 启用 OAuth2 登录功能
                .oauth2Login(oauth2 -> oauth2
                        // 自定义登录页地址（可选，默认会生成登录页）
                        .loginPage("/login")
                        // 登录成功后强制跳转
                        .defaultSuccessUrl("/login/github/success", true)
                )

                // 使用默认登录页
//                .formLogin(withDefaults())
                // 配置自定义登录页
                // 前后端不分离的模式
                .formLogin(form -> {
                    form.loginPage("/login")
                            // 配置认证成功处理器
                            .successHandler(new CustomAuthenticationSuccessHandler())
                            // 配置认证失败处理器
                            .failureHandler(new CustomAuthenticationFailureHandler())
                            // 配置登录页无需授权即可访问
                            .permitAll();
                })

                // 配置注销处理器
                .logout(logout -> {
                    logout.logoutSuccessHandler(new CustomLogoutSuccessHandler());
                })

                // 跨域处理
                .cors(withDefaults())

                // 关闭跨站伪造攻击
                .csrf(csrf -> csrf.disable())

                // 配置异常处理
                .exceptionHandling(exception -> {
                    // 请求未授权的接口
                    exception.accessDeniedHandler(new CustomAccessDeniedHandler());
                    // 未认证而请求被保护的接口时，调用此处理类
                    exception.authenticationEntryPoint(new CustomAuthenticationEntryPoint());
                })
                .build();
    }
}
